//package asm.dispatch;
//
//import jdk.internal.access.JavaLangAccess;
//import jdk.internal.access.SharedSecrets;
//import org.ricks.common.Context;
//import org.ricks.common.Tuple;
//import org.ricks.dispatch.Dispatcher;
//import org.ricks.dispatch.DispatcherDump;
//import org.ricks.ioc.App;
//import org.ricks.ioc.Bean;
//import org.ricks.ioc.Message;
//import org.ricks.net.ActionMethod;
//import org.ricks.ioc.bean.factory.AbstractBeanFactory;
//import org.ricks.log.Logger;
//import org.ricks.utils.FileUtil;
//
//import java.lang.reflect.Method;
//import java.util.ArrayList;
//import java.util.List;
//
///**
// * @author chenwei
// * @Description:指令调用管理器
// * 类加载的问题，导致自定义加载器
// * 方案一：
// *     static final JavaLangAccess JLA = SharedSecrets.getJavaLangAccess();
// *     Class clazz = JLA.defineClass(DispatchManager.class.getClassLoader(),"org.demon.dispatch.Dispatcher",data,null,null);
// * 方案二：
// *            Method mdDefineClass = ClassLoader.class
// *                     .getDeclaredMethod("defineClass",String.class,byte[].class,int.class,int.class);
// *             mdDefineClass.setAccessible(true);
// *             String className = "org.demon.dispatch.Dispatcher";
// *             Class clazz = (Class)mdDefineClass.invoke(DispatchManager.class.getClassLoader(),new Object[]{
// *                     className,data,0,data.length
// *             });
// *
// *  以上方案都不优雅，需要调用其它module 而jdk9之后 module之间互相调用 需要在启动jvm加上访问参数
// *
// *
// *  使用了 openJdk  JavaLangAccess ，就必须在启动参数加上 --add-opens java.base/jdk.internal.access=ALL-UNNAMED
// *  破坏了 Jdk9 module 之间不能调用的机制
// *
// * @date 2021/3/1917:47
// */
//public class DispatchManager {
//
//    private static JavaLangAccess LANG_ACCESS;
//    static {
//        LANG_ACCESS = SharedSecrets.getJavaLangAccess();
//    }
//
//
//    public static void init(App context) {
//        try {
//            String dispatch_path = FileUtil.class.getProtectionDomain().getCodeSource().getLocation().getPath() + "org/ricks/dispatch/Dispatcher.class";
//            System.err.println(dispatch_path);
//            byte[] data = DispatcherDump.dump(initPairs(context));
////            FileOutputStream fos = new FileOutputStream(dispatch_path);
////            fos.write(data);
////            fos.close();
//            Context c = new Context<Short,Byte[]>(null,new Message((short)4000,new byte[0]));
//            Context c1 = new Context<Short,Byte[]>(null,new Message((short)4001,new byte[0]));
//            Context c2 = new Context<Short,Byte[]>(null,new Message((short)1,new byte[0]));
////            Dispatcher d = new Dispatcher();
////            ClassLoad classLoad = new ClassLoad(DispatchManager.class.getClassLoader(),data);
////            Class clazz = classLoad.loadClass("org.demon.dispatch.Dispatcher");
////            Class clazz = classLoad.findClass("org.demon.dispatch.Dispatcher");
////            Class clazz = classLoad.defineClassToJvm("org.demon.dispatch.Dispatcher",data);
//
////            Method mdDefineClass = ClassLoader.class
////                    .getDeclaredMethod("defineClass",String.class,byte[].class,int.class,int.class);
////            mdDefineClass.setAccessible(true);
////            String className = "org.demon.dispatch.Dispatcher";
////            Class clazz = (Class)mdDefineClass.invoke(DispatchManager.class.getClassLoader(),new Object[]{
////                    className,data,0,data.length
////            });
//
//            Class clazz = LANG_ACCESS.defineClass(DispatchManager.class.getClassLoader(),"org.demon.dispatch.Dispatcher",data,null,null);
////            Class<?> clazz = SharedSecrets.getJavaLangAccess()
////                    .defineClass(DispatchManager.class.getClassLoader(), "org.demon.dispatch.Dispatcher", data,null,null);
//
////            Class clazz = ClassLoaderUtil.defineClass1(DispatchManager.class.getClassLoader(),"org.demon.dispatch.Dispatcher",data,0,data.length,null,null);
//
//            System.err.println(clazz.getClassLoader());
//            Method mm = clazz.getDeclaredMethod("dispatcher",Context.class);
//            Dispatcher dispatcher = (Dispatcher) clazz.newInstance();
//			mm.invoke(dispatcher,c);
//
//            dispatcher.dispatcher(c2);
//            Dispatcher.dispatcher(c1);
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
//    }
//
//    public static class ClassLoad extends ClassLoader {
//
//        private byte[] data;
//
//        public ClassLoad(byte[] data) {
//            this.data = data;
//        }
//
//        public ClassLoad(ClassLoader parent, byte[] data) {
//            super(parent);
//            this.data = data;
//        }
//
//
//        @Override
//        public Class<?> findClass(String className) throws ClassNotFoundException {
//            return this.defineClass(className, data, 0, data.length,null);
//        }
//    }
//
//    public static List<Tuple> initPairs(App context) {
//        List<Tuple> pairs = new ArrayList<>();
//        AbstractBeanFactory beanFactory = context.getBeanFactory();
//        if(beanFactory != null) {
//            List<Object> beans = beanFactory.getBeansForAnnotation(Bean.class);
//            if (!beans.isEmpty()) {
//                for (Object obj : beans) {
//                    try {
//                        Method[] methods = obj.getClass().getMethods();
//                        for (Method method : methods) {
//                            ActionMethod messageHandler = method.getAnnotation(ActionMethod.class);
//                            if (messageHandler == null) {
//                                continue;
//                            }
//                            Class<?>[] parameterClazzes = method.getParameterTypes();
//                            if (parameterClazzes.length != 1) {
//                                throw new IllegalArgumentException("消息处理方法的参数不正确，参数必须是一个。");
//                            }
//                            Class<?> commandClass = parameterClazzes[0];
//                            if (!Context.class.isAssignableFrom(commandClass)) {
//                                continue;
//                            }
//                            pairs.add(new Tuple(messageHandler.messageId(),getClassName(obj).replace("/","."),method.getName()));
//                        }
//                    } catch (Exception e) {
//                        Logger.error("", e);
//                    }
//                }
//            }
//        }
//        return pairs;
//    }
//
//    private static String getClassName(Object obj) {
//        String beanName = obj.getClass().getName();
//        return beanName.replace(".","/");
//    }
//}
